﻿using Microsoft.Extensions.Options;
using Microsoft.IdentityModel.JsonWebTokens;
using Microsoft.IdentityModel.Tokens;
using System.IdentityModel.Tokens.Jwt;
using System.Security.Claims;
using System.Text;

namespace Magic.Core;


public interface IJWTBuilder
{
    string CreateToken(Dictionary<string, object> payload);

    JsonWebToken ReadJwtToken(string accessToken);
}

/// <summary>
/// JWT 加解密
/// </summary>
public class JWTBuilder : IJWTBuilder
{
    private readonly IOptions<JWTSettingsOptions> _options;
    public JWTBuilder(IOptions<JWTSettingsOptions> options)
    {
        this._options = options;
    }

    public string CreateToken(Dictionary<string, object> payload)
    {
        var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_options.Value.IssuerSigningKey));
        var credentials = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);

        List<Claim> claims = new List<Claim>();

        if (_options.Value.ValidateIssuer.HasValue && _options.Value.ValidateIssuer.Value)
        {
            claims.Add(new Claim(System.IdentityModel.Tokens.Jwt.JwtRegisteredClaimNames.Iss, _options.Value.ValidIssuer));
        }
        if (_options.Value.ValidateAudience.HasValue && _options.Value.ValidateAudience.Value)
        {
            claims.Add(new Claim(System.IdentityModel.Tokens.Jwt.JwtRegisteredClaimNames.Aud, _options.Value.ValidAudience));
        }

        foreach (KeyValuePair<string, object> item in payload)
        {
            claims.Add(new Claim(item.Key, item.Value.ToString()));
        }

        SecurityToken securityToken = new JwtSecurityToken(
        signingCredentials: credentials,
        expires: DateTime.Now.AddMinutes(_options.Value.ExpiredTime.Value),//过期时间
        claims: claims
         );

        //生成jwt令牌
        string accessToken = new JwtSecurityTokenHandler().WriteToken(securityToken);
        return accessToken;
    }

    /// <summary>
    /// 读取token信息，不含验证
    /// </summary>
    /// <param name="accessToken"></param>
    /// <returns></returns>
    public JsonWebToken ReadJwtToken(string accessToken)
    {
        JsonWebTokenHandler jsonWebTokenHandler = new JsonWebTokenHandler();
        if (jsonWebTokenHandler.CanReadToken(accessToken))
        {
            return jsonWebTokenHandler.ReadJsonWebToken(accessToken);
        }

        return null;
    }


}
